package com.example.demo.service.Impl;


import com.example.demo.ao.NetIncreaseCapAo;
import com.example.demo.mapper.NetIncreaseCapMapper;
import com.example.demo.service.NetIncreaseCapService;
import com.example.demo.vo.NetCapResultVo;
import com.example.demo.vo.NetCapTotalVo;
import com.example.demo.vo.NetCapVo;
import com.example.demo.vo.NetIncreaseCapVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.DoubleSummaryStatistics;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class NetIncreaseCapServiceImpl implements NetIncreaseCapService {
    @Autowired
    private NetIncreaseCapMapper netIncreaseCapMapper;


    @Override
    public List<NetIncreaseCapVo> getNetIncreaseCap(NetIncreaseCapAo netIncreaseCapAo) {
        /**获取传入开始时间年一月**/
        YearMonth nowYear = YearMonth.parse(netIncreaseCapAo.getStartTime(), DateTimeFormatter.ofPattern("yyyyMM"));
        String yearOne = nowYear.withMonth(1).format(DateTimeFormatter.ofPattern("yyyyMM"));
        netIncreaseCapAo.setStartTimeTotal(yearOne);

        /**当月值计算**/
        List<NetCapVo> capCustList = getCapCustList(netIncreaseCapAo);

        /**累计值计算**/
        List<NetCapTotalVo> capCustTotalList = getCapCustTotalList(netIncreaseCapAo);

        List<NetCapVo> result = new ArrayList<>();
        List<NetCapTotalVo> resultTotal = new ArrayList<>();
//        Map<String, DoubleSummaryStatistics> mapCapCust = capCustList.stream().collect(Collectors.groupingBy(d -> d.getMgtOrgCode() + "-" + d.getIndCls(), Collectors.summarizingDouble(NetCapVo::getTSettleQtyPresent)));
//        for (Map.Entry<String, DoubleSummaryStatistics> listEntry : mapCapCust.entrySet()) {
//            NetCapVo netCapVo = new NetCapVo();
//            netCapVo.setTSettleQtyPresent(listEntry.getValue().getSum());
//            netCapVo.setMgtOrgCode(listEntry.getKey().split("-")[0]);
//            netCapVo.setIndCls(listEntry.getKey().split("-")[1]);
//            result.add(netCapVo);
//        }

        /**当月**/
        Map<String, List<NetCapVo>> mapCapCust = capCustList.stream().collect(Collectors.groupingBy(NetCapVo::getIndCls));
        for (Map.Entry<String, List<NetCapVo>> listEntry : mapCapCust.entrySet()) {
            double settleQty = 0.00;
            double highElecThree = 0.00;
            double highElecTen = 0.00;
            double lowElec = 0.00;
            for (NetCapVo netCapVo : listEntry.getValue()) {
                settleQty += netCapVo.getTSettleQtyPresent();
                highElecThree += netCapVo.getHighElec35Present();
                highElecTen += netCapVo.getHighElec10Present();
                lowElec += netCapVo.getLowElec10Present();
            }
            NetCapVo netCapVo = new NetCapVo();
            netCapVo.setTSettleQtyPresent(settleQty);
            netCapVo.setHighElec35Present(highElecThree);
            netCapVo.setHighElec10Present(highElecTen);
            netCapVo.setLowElec10Present(lowElec);
            netCapVo.setIndCls(listEntry.getKey());
            result.add(netCapVo);
        }

        /**累计**/
        Map<String, List<NetCapTotalVo>> mapCapCustTotal = capCustTotalList.stream().collect(Collectors.groupingBy(NetCapTotalVo::getIndClsTotal));
        for (Map.Entry<String, List<NetCapTotalVo>> listEntry : mapCapCustTotal.entrySet()) {
            double settleQty = 0.00;
            double highElecThree = 0.00;
            double highElecTen = 0.00;
            double lowElec = 0.00;
            for (NetCapTotalVo netCapTotalVoVo : listEntry.getValue()) {
                settleQty += netCapTotalVoVo.getTSettleQtyPresentTotal();
                highElecThree += netCapTotalVoVo.getHighElec35PresentTotal();
                highElecTen += netCapTotalVoVo.getHighElec10PresentTotal();
                lowElec += netCapTotalVoVo.getLowElec10PresentTotal();
            }
            NetCapTotalVo netCapTotalVoVo = new NetCapTotalVo();
            netCapTotalVoVo.setTSettleQtyPresentTotal(settleQty);
            netCapTotalVoVo.setHighElec35PresentTotal(highElecThree);
            netCapTotalVoVo.setHighElec10PresentTotal(highElecTen);
            netCapTotalVoVo.setLowElec10PresentTotal(lowElec);
            netCapTotalVoVo.setIndClsTotal(listEntry.getKey());
            resultTotal.add(netCapTotalVoVo);
        }

        List<NetIncreaseCapVo> netIncreaseCap = netIncreaseCapMapper.getNetIncreaseCap(netIncreaseCapAo);
        List<NetIncreaseCapVo> netIncreaseCapTotal = netIncreaseCapMapper.getNetIncreaseCapTotal(netIncreaseCapAo);
        for (NetIncreaseCapVo capOne : netIncreaseCap) {
            for (NetIncreaseCapVo capTwo : netIncreaseCapTotal) {
                if (capOne.getIndCls().equals(capTwo.getIndCls())){
                    capOne.setCustNumYear(capTwo.getCustNum());
                    capOne.setCapYear(capTwo.getCap());
                    capOne.setElecYear(capTwo.getElec());
                    capOne.setHighNum35Year(capTwo.getHighNum35());
                    capOne.setHighCap35Year(capTwo.getHighCap35());
                    capOne.setHighElec35Year(capTwo.getHighElec35());
                    capOne.setHighNum10Year(capTwo.getHighNum10());
                    capOne.setHighCap10Year(capTwo.getHighCap10());
                    capOne.setHighElec10Year(capTwo.getHighElec10());
                    capOne.setLowNum10Year(capTwo.getLowNum10());
                    capOne.setLowCap10Year(capTwo.getLowCap10());
                    capOne.setLowElec10Year(capTwo.getLowElec10());
                }
            }
        }
        for (NetIncreaseCapVo netIncreaseCapVo : netIncreaseCap) {
            for (NetCapVo netCapVo : result) {
                if (netIncreaseCapVo.getIndCls().equals(netCapVo.getIndCls())){
                    netIncreaseCapVo.setElec(netIncreaseCapVo.getElec() - netCapVo.getTSettleQtyPresent());
                    netIncreaseCapVo.setHighElec35(netIncreaseCapVo.getHighElec35() - netCapVo.getHighElec35Present());
                    netIncreaseCapVo.setHighElec10(netIncreaseCapVo.getHighElec10() - netCapVo.getHighElec10Present());
                    netIncreaseCapVo.setLowElec10(netIncreaseCapVo.getLowElec10() - netCapVo.getLowElec10Present());
                }
            }
            for (NetCapTotalVo netCapTotalVo : resultTotal) {
                if (netIncreaseCapVo.getIndCls().equals(netCapTotalVo.getIndClsTotal())){
                    netIncreaseCapVo.setElecYear(netIncreaseCapVo.getElecYear() - netCapTotalVo.getTSettleQtyPresentTotal());
                    netIncreaseCapVo.setHighElec35Year(netIncreaseCapVo.getHighElec35Year() - netCapTotalVo.getHighElec35PresentTotal());
                    netIncreaseCapVo.setHighElec10Year(netIncreaseCapVo.getHighElec10Year() - netCapTotalVo.getHighElec10PresentTotal());
                    netIncreaseCapVo.setLowElec10Year(netIncreaseCapVo.getLowElec10Year() - netCapTotalVo.getLowElec10PresentTotal());
                }
            }
        }


        return netIncreaseCap;
    }



    /**当月**/
    private List<NetCapVo> getCapCustList(NetIncreaseCapAo netIncreaseCapAo){
        /**获取增容用户、用户编号、立户日期、归档日期**/
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        DateTimeFormatter monthMattrt = DateTimeFormatter.ofPattern("yyyyMM");
        /**解析结束时间,获取月最后一天**/
        YearMonth day = YearMonth.parse(netIncreaseCapAo.getEndTime(), monthMattrt);
        String lastDayChar = day.atEndOfMonth().format(formatter);
        LocalDate lastDay = LocalDate.parse(lastDayChar, formatter);
        List<NetCapVo> capCustList = netIncreaseCapMapper.getCapCust(netIncreaseCapAo);
        System.out.println(capCustList.size());
        /**当月**/
        for (NetCapVo capCust : capCustList) {
            NetCapResultVo netCapResultVo = new NetCapResultVo();
            LocalDate acmpTime = LocalDate.parse(capCust.getAcmpTime(), formatter);
            LocalDate estabAcctDate = LocalDate.parse(capCust.getEstabAcctDate(), formatter);
            /**归档日期到结束日期相差多少天**/
            long lastAcmp = Math.abs(ChronoUnit.DAYS.between(lastDay, acmpTime));
            /**相差是否有365天**/
            long timeDifference = Math.abs(ChronoUnit.DAYS.between(acmpTime, estabAcctDate));
            /**归档日期到结束日期**/
            LocalDate parseAcmp = LocalDate.parse(capCust.getAcmpTime(), formatter);
            if (timeDifference >= 365){
                netIncreaseCapAo.setStartCust(parseAcmp.minusDays(365).format(monthMattrt));
                netIncreaseCapAo.setEndCust(parseAcmp.format(monthMattrt));
                netIncreaseCapAo.setCustNo(capCust.getCustNo());
                netCapResultVo = netIncreaseCapMapper.getCapCustQty(netIncreaseCapAo);
                /**计算减数**/
                netCapResultVo.setIndCls(netCapResultVo.getIndCls());
                netCapResultVo.setTSettleQtyPresent(netCapResultVo.getTSettleQty() / 365 * lastAcmp);
                netCapResultVo.setHighElec35Present(netCapResultVo.getHighElec35() / 365 * lastAcmp);
                netCapResultVo.setHighElec10Present(netCapResultVo.getHighElec10() / 365 * lastAcmp);
                netCapResultVo.setLowElec10Present(netCapResultVo.getLowElec10() / 365 * lastAcmp);

            } else {
                LocalDate parseEstabAcct = LocalDate.parse(capCust.getEstabAcctDate(), formatter);
                netIncreaseCapAo.setStartCust(parseEstabAcct.format(monthMattrt));
                netIncreaseCapAo.setEndCust(parseAcmp.format(monthMattrt));
                netIncreaseCapAo.setCustNo(capCust.getCustNo());
                netCapResultVo = netIncreaseCapMapper.getCapCustQty(netIncreaseCapAo);
                /**计算减数**/
                netCapResultVo.setIndCls(netCapResultVo.getIndCls());
                netCapResultVo.setTSettleQtyPresent(netCapResultVo.getTSettleQty() / timeDifference * lastAcmp);
                netCapResultVo.setHighElec35Present(netCapResultVo.getHighElec35() / timeDifference * lastAcmp);
                netCapResultVo.setHighElec10Present(netCapResultVo.getHighElec10() / timeDifference * lastAcmp);
                netCapResultVo.setLowElec10Present(netCapResultVo.getLowElec10() / timeDifference * lastAcmp);
            }

            /**根据上述处理，查询用户的总电量、ggdw、行业分类**/
            try {
                BeanUtils.copyProperties(netCapResultVo, capCust);
            } catch (Exception e) {
                System.out.println("属性复制失败: " + e.getMessage());
                // 初始化默认值或跳过
            }
        }
        return capCustList;
    }





    private List<NetCapTotalVo> getCapCustTotalList(NetIncreaseCapAo netIncreaseCapAo){
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        DateTimeFormatter monthMattrt = DateTimeFormatter.ofPattern("yyyyMM");
        /**解析结束时间,获取月最后一天**/
        YearMonth day = YearMonth.parse(netIncreaseCapAo.getEndTime(), monthMattrt);
        String lastDayChar = day.atEndOfMonth().format(formatter);
        LocalDate lastDay = LocalDate.parse(lastDayChar, formatter);
        /**获取累计用户、立户日期、归档日期**/
        List<NetCapTotalVo> capCustTotalList = netIncreaseCapMapper.getCapCustTotal(netIncreaseCapAo);
        for (NetCapTotalVo capCustTotal : capCustTotalList) {
            NetCapResultVo netCapResultVo = new NetCapResultVo();
            LocalDate acmpTimeTotal = LocalDate.parse(capCustTotal.getAcmpTimeTotal(), formatter);
            LocalDate estabAcctDateTotsl = LocalDate.parse(capCustTotal.getEstabAcctDateTotal(), formatter);
            /**归档日期到结束日期相差多少天**/
            long lastAcmpTotal = Math.abs(ChronoUnit.DAYS.between(lastDay, acmpTimeTotal));
            /**相差是否有365天**/
            long timeDifferenceTotal = Math.abs(ChronoUnit.DAYS.between(acmpTimeTotal, estabAcctDateTotsl));
            /**归档日期到结束日期**/
            LocalDate parseAcmpTotal = LocalDate.parse(capCustTotal.getAcmpTimeTotal(), formatter);
            if (timeDifferenceTotal >= 365){
                netIncreaseCapAo.setStartCustTotal(parseAcmpTotal.minusDays(365).format(monthMattrt));
                netIncreaseCapAo.setEndCustTotal(parseAcmpTotal.format(monthMattrt));
                netIncreaseCapAo.setCustNoTotal(capCustTotal.getCustNoTotal());
                netCapResultVo = netIncreaseCapMapper.getCapCustQtyTotal(netIncreaseCapAo);
                /**计算减数**/
                netCapResultVo.setIndCls(netCapResultVo.getIndClsTotal());
                netCapResultVo.setTSettleQtyPresentTotal(netCapResultVo.getTSettleQtyTotal() / 365 * lastAcmpTotal);
                netCapResultVo.setHighElec35PresentTotal(netCapResultVo.getHighElec35Total() / 365 * lastAcmpTotal);
                netCapResultVo.setHighElec10PresentTotal(netCapResultVo.getHighElec10Total() / 365 * lastAcmpTotal);
                netCapResultVo.setLowElec10PresentTotal(netCapResultVo.getLowElec10Total() / 365 * lastAcmpTotal);
            }else {
                LocalDate parseEstabAcctTotal = LocalDate.parse(capCustTotal.getEstabAcctDateTotal(), formatter);
                netIncreaseCapAo.setStartCustTotal(parseEstabAcctTotal.format(monthMattrt));
                netIncreaseCapAo.setEndCustTotal(parseAcmpTotal.format(monthMattrt));
                netIncreaseCapAo.setCustNoTotal(capCustTotal.getCustNoTotal());
                netCapResultVo = netIncreaseCapMapper.getCapCustQtyTotal(netIncreaseCapAo);
                /**计算减数**/
                netCapResultVo.setIndCls(netCapResultVo.getIndClsTotal());
                netCapResultVo.setTSettleQtyPresentTotal(netCapResultVo.getTSettleQtyTotal() / timeDifferenceTotal * lastAcmpTotal);
                netCapResultVo.setHighElec35PresentTotal(netCapResultVo.getHighElec35Total() / timeDifferenceTotal * lastAcmpTotal);
                netCapResultVo.setHighElec10PresentTotal(netCapResultVo.getHighElec10Total() / timeDifferenceTotal * lastAcmpTotal);
                netCapResultVo.setLowElec10PresentTotal(netCapResultVo.getLowElec10Total() / timeDifferenceTotal * lastAcmpTotal);
            }
            try {
                BeanUtils.copyProperties(netCapResultVo, capCustTotal);
            } catch (Exception e) {
                System.out.println("属性复制失败: " + e.getMessage());
                // 初始化默认值或跳过
            }
        }
        return capCustTotalList;
    }
}
